package com.noah.framework.exception.base;

import com.noah.framework.exception.AbstractExceptionEnum;
import com.noah.framework.exception.constant.ExceptionConstant;

/**
 * 所有业务异常的基类
 * 在抛出异常时，务必带上AbstractExceptionEnum枚举
 * 业务异常分为三种
 * 第一种是用户端操作的异常，例如用户输入参数为空，用户输入用户名密码不正确
 * 第二种是当前系统业务逻辑异常，例如系统执行出错、磁盘空间不足等
 * 第三种是第三方系统调用出错，例如文件服务调用失败，RPC调用超时
 *
 * @author noah
 * 2023/9/5 15:01
 */
public class ServiceException extends RuntimeException {
    /**
     * 错误码
     */
    private String errorCode;

    /**
     * 返回给用户的提示信息
     */
    private String userTip;

    /**
     * 异常所在的模块名称
     */
    private String moduleName;

    /**
     * 异常携带的数据参数
     */
    private Object data;

    /**
     * 根据模块名、错误码、用户提示直接抛出异常
     *
     * @param moduleName
     * @param errorCode
     * @param userTip
     */
    public ServiceException(String moduleName, String errorCode, String userTip) {
        super(userTip);
        this.errorCode = errorCode;
        this.moduleName = moduleName;
        this.userTip = userTip;
    }

    /**
     * 如果要直接抛出ServiceException异常，可以使用该构造函数
     *
     * @param moduleName
     * @param exceptionEnum
     */
    public ServiceException(String moduleName, AbstractExceptionEnum exceptionEnum) {
        super(exceptionEnum.getUserTip());
        this.moduleName = moduleName;
        this.errorCode = exceptionEnum.getErrorCode();
        this.userTip = exceptionEnum.getUserTip();
    }

    /**
     * 不建议使用该构造函数直接抛出异常，会缺少对应的模块类
     *
     * @param exceptionEnum
     */
    public ServiceException(AbstractExceptionEnum exceptionEnum) {
        super(exceptionEnum.getUserTip());
        this.moduleName = ExceptionConstant.DefaultModuleName;
        this.errorCode = exceptionEnum.getErrorCode();
        this.userTip = exceptionEnum.getUserTip();
    }

    /**
     * 携带数据参数的异常类说明
     *
     * @param moduleName
     * @param errorCode
     * @param userTip
     * @param data
     */
    public ServiceException(String moduleName, String errorCode, String userTip, Object data) {
        super(userTip);
        this.moduleName = moduleName;
        this.errorCode = errorCode;
        this.userTip = userTip;
        this.data = data;
    }
}
